package com.xbongbong.saas.analytical.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.pro.constant.AttrLenthConstant;
import com.xbongbong.pro.enums.CommunicatePlanNotifyTypeEnum;
import com.xbongbong.pro.enums.errorcodes.CommuicatePlanErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.saas.analytical.SaasValidateAnalyticalService;
import com.xbongbong.saas.domain.entity.CustomerUserEntity;
import com.xbongbong.saas.enums.ExecutorCheckBoxEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.CommunicatePlanEnum;
import com.xbongbong.saas.enums.business.CustomerCommunicateEnum;
import com.xbongbong.saas.enums.dictionary.CommunicatePlanStatusEnum;
import com.xbongbong.saas.help.SaasDataInitHelp;
import com.xbongbong.saas.help.SaveFormatHelp;
import com.xbongbong.saas.model.CustomerUserModel;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getIntegerOrDefaultFromFormData;

/**
 * @author 吴峰
 * @date 2021/07/15 17:15
 */
@Service("communicatePlanAnalyticalServiceImpl")
public class CommunicatePlanValidateAnalyticalServiceImpl implements SaasValidateAnalyticalService {

    @Resource
    private CustomerUserModel customerUserModel;

    @Override
    public List<Integer> type() {
        return Arrays.asList(XbbRefTypeEnum.COMMUNICATE_PLAN.getCode());
    }

    @Override
    public void analyticalData(ValidateDataDTO validateDataDTO) throws XbbException {
        beforeSave(validateDataDTO);
    }
    
    public void beforeSave(ValidateDataDTO validateDataDTO) throws XbbException {
        String corpid = validateDataDTO.getCorpid();
        JSONObject data = validateDataDTO.getData();
        Long id = validateDataDTO.getDataId();
        SaveFormatHelp.formatLinkBusiness4Save(data, CommunicatePlanEnum.LINK_CUSTOMER.getAttr(), CommunicatePlanEnum.CUSTOMER_NAME_LINK_TEXT.getAttr(), CommunicatePlanEnum.LINK_CUSTOMER.getFieldType());
        if (id == null || id < 1) {
            // 新建访客计划状态为未跟进
            data.put(CommunicatePlanEnum.STATUS.getAttr(), CommunicatePlanStatusEnum.NO_FOLLOW.getCode());
            // 新建不是延期
            data.put(CommunicatePlanEnum.IS_DELAY.getAttr(), 0);
        }
        String name = FastJsonHelper.getStringFromFormData(data, CommunicatePlanEnum.NAME.getAttr());
        if (name != null && name.length() > AttrLenthConstant.NAME_MAX_LENGTH) {
            throw new XbbException(CommuicatePlanErrorCodeEnum.API_ERROR_214007);
        }
        String memo = FastJsonHelper.getStringFromFormData(data, CommunicatePlanEnum.MEMO.getAttr());
        if (memo != null && memo.length() > AttrLenthConstant.MEMO_MAX_LENGTH) {
            throw new XbbException(CommuicatePlanErrorCodeEnum.API_ERROR_214008);
        }
        Long communicateTime = FastJsonHelper.getLongFromFormData(data, CommunicatePlanEnum.COMMUNICATE_TIME.getAttr());
        Integer notifyType = getIntegerOrDefaultFromFormData(data, CommunicatePlanEnum.NOTIFY_TYPE.getAttr(), CommunicatePlanNotifyTypeEnum.NO_NOTIFY.getCode());
        Long notifyTime = FastJsonHelper.getLongFromFormData(data, CommunicatePlanEnum.NOTIFY_TIME.getAttr());
        notifyTime = checkCommunicateTime(communicateTime, notifyType, notifyTime);
        if (notifyType.equals(CommunicatePlanNotifyTypeEnum.NO_NOTIFY.getCode())) {
            notifyTime = null;
        }
        data.put(CommunicatePlanEnum.NOTIFY_TIME.getAttr(), notifyTime);
        Long customerId = FastJsonHelper.getLongOrDefaultFromFormData(data, CommunicatePlanEnum.LINK_CUSTOMER.getAttr(), 0L);
        validateExeCutor(data, customerId, corpid);
        for (Map.Entry<String,Object> entry : SaasDataInitHelp.initCommunicatePlan().entrySet()){
            SaasDataInitHelp.antDataSet(data,entry.getKey(),entry.getValue());
        }
        validateDataDTO.setData(data);
    }

    /**
     * 执行人校验
     *
     * @param data
     * @param customerId
     * @param corpid
     * @throws
     * @author long.rao
     * @date 2019-02-20 21:51
     */
    private void validateExeCutor(JSONObject data, Long customerId, String corpid) throws XbbException{
        try {
            boolean isManager = false;
            boolean isCooper = false;
            boolean isCustom = false;
            JSONArray checkArray = data.getJSONArray(CommunicatePlanEnum.EXECUTOR.getAttr());
            for (Object obj : checkArray) {
                Integer check = Integer.parseInt(obj.toString());
                if (Objects.equals(check, ExecutorCheckBoxEnum.MAIN_USER_CHECK.getCode())) {
                    isManager = true;
                }
                if (Objects.equals(check, ExecutorCheckBoxEnum.COOPER_USER_CHECK.getCode())) {
                    isCooper = true;
                }
                if (Objects.equals(check, ExecutorCheckBoxEnum.CUSTOM_CHECK.getCode())) {
                    isCustom = true;
                }
            }
            Map<Long, List<String>> customerMainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<Long, List<String>> customerCoopUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            if (isManager || isCooper) {
                //查找所有客户的协同团队
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("del", 0);
                param.put("customerId", customerId);
                param.put("corpid", corpid);
                List<CustomerUserEntity> customerUserList = customerUserModel.findEntitys(param);
                for (CustomerUserEntity customerUserEntity : customerUserList) {
                    String cUserId = customerUserEntity.getUserId();
                    Integer isMain = customerUserEntity.getIsMain() == null ? 0 : customerUserEntity.getIsMain();
                    List<String> mainUser = customerMainUserMap.get(customerId) == null ? new ArrayList<>() : customerMainUserMap.get(customerId);
                    List<String> coopUser = customerCoopUserMap.get(customerId) == null ? new ArrayList<>() : customerCoopUserMap.get(customerId);
                    if (isMain == 1) {
                        mainUser.add(cUserId);
                    } else if (isMain == 0) {
                        coopUser.add(cUserId);
                    }
                    customerMainUserMap.put(customerId, mainUser);
                    customerCoopUserMap.put(customerId, coopUser);
                }
            }

            //执行人员
            List<String> thisUserIds = new ArrayList<>();
            JSONArray userArray = data.getJSONArray(CommunicatePlanEnum.EXECUTOR_LINKED_TEXT.getAttr());
            if (isCustom && userArray != null) {
                for (Object userObj : userArray) {
                    String customUserId = userObj.toString();
                    thisUserIds.add(customUserId);
                }
            }
            //只选择协同人&&关联客户无协同人 || 选择协同人和自定义&&关联客户无协同人&&自定义没有添加自定义人员 || 只选择自定义&&没有添加自定义人员
            if ((!isManager && isCooper && !isCustom && customerCoopUserMap.get(customerId).size() < 1)
                    || (!isManager && isCooper && isCustom && thisUserIds.size() < 1 && customerCoopUserMap.get(customerId).size() < 1)
                    || (!isManager && !isCooper && thisUserIds.size() < 1)) {
                throw new XbbException(CommuicatePlanErrorCodeEnum.API_ERROR_214002);
            }
        } catch (XbbException e){
            throw e;
        } catch (Exception e) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100015);
        }
    }

    /**
     * 校验执行时间和提醒时间
     *
     * @param communicateTime 执行时间
     * @param remindType 提醒类型
     * @param notifyTime 提醒时间
     * @throws XbbException
     * @author long.rao
     * @date 2019-02-16 22:24
     */
    public Long checkCommunicateTime(Long communicateTime, Integer remindType, Long notifyTime) throws XbbException {
        long now = DateUtil.getInt();
        if (communicateTime == null || communicateTime == 0) {
            throw new XbbException(CommuicatePlanErrorCodeEnum.API_ERROR_214003);
        } else if (communicateTime < now) {
            throw new XbbException(CommuicatePlanErrorCodeEnum.API_ERROR_214001);
        }
        if (remindType == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002);
        }
        CommunicatePlanNotifyTypeEnum communicatePlanNotifyTypeEnum = CommunicatePlanNotifyTypeEnum.getByCode(remindType);
        switch (communicatePlanNotifyTypeEnum) {
            case NO_NOTIFY:
                notifyTime = communicateTime;
                break;
            case ADVANCE_ONE_QUARTER_HOUR:
                notifyTime = communicateTime - TimeConstant.SECONDS_PER_MINUTE * 15;
                break;
            case ADVANCE_ONE_HOUR:
                notifyTime = communicateTime - TimeConstant.SECONDS_PER_HOUR;
                break;
            case ADVANCE_ONE_DAY:
                notifyTime = communicateTime - TimeConstant.SECONDS_PER_DAY;
                break;
            case ADVANCE_THREE_DAY:
                notifyTime = communicateTime - TimeConstant.SECONDS_PER_DAY * 3;
                break;
            case ADVANCE_ONE_WEEK:
                notifyTime = communicateTime - TimeConstant.SECONDS_PER_WEEK;
                break;
            case CUSTOM_TIME:
                // 自定义提醒不需要做处理
                break;
            default:
                break;
        }
        if (notifyTime == null) {
            notifyTime = communicateTime;
        }
        if (notifyTime > communicateTime) {
            throw new XbbException(CommuicatePlanErrorCodeEnum.API_ERROR_214004);
        } else if (notifyTime < now) {
            throw new XbbException(CommuicatePlanErrorCodeEnum.API_ERROR_214004);
        }
        return notifyTime;
    }
}
